home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Taifun / Taifun 175 (1991-09-10)(Manewaldt, A.)(DE)(PD).zip / Taifun 175 (1991-09-10)(Manewaldt, A.)(DE)(PD).adf / Term / Libs.LZH / XprXModem / xprxmodem.c < prev    next >
C/C++ Source or Header  |  1991-07-26  |  11KB  |  529 lines

  1. /*
  2.  * This XPR is based on bmodem - the BIX modem program
  3.  * 
  4.  * by David Betz, BYTE Magazine/BIX
  5.  * 
  6.  * bmodem consists of three files: bmodem.c, dlink.c, mdio.c. bmodem.c and
  7.  * mdio.c were substantially modified and merged into this file, xprxmodem.c
  8.  * 
  9.  * dlink.c was ANSIsized and made re-entrant for xprlib by m. boucher.
  10.  * 
  11.  * Modified substantially by W.G.J. Langeveld for use in VLT.
  12.  * 
  13.  * Transformed into XPR by Marc Boucher
  14.  * (BIX: mboucher Internet: marc@CAM.ORG)
  15.  * 
  16.  */
  17.  
  18. static char _StAmP[] = "Copyright ©1990 Marc Boucher, All Rights Reserved -- Compiled: " __DATE__ " " __TIME__;
  19.  
  20. #include <string.h>
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <ctype.h>
  24.  
  25. #include "xprxmodem.h"
  26.  
  27. #include "proto-callback.h"
  28. #include "proto-dlink.h"
  29.  
  30. long XProtocolCleanup(struct XPR_IO * IO)
  31. {
  32.     if (IO->xpr_data) {
  33.         FreeMem(IO->xpr_data, sizeof(struct XProtocolData));
  34.         IO->xpr_data = NULL;
  35.     }
  36.     return (1);
  37. }
  38.  
  39. static char *MYstrtok(char *cmd, char *toks, char **ptr)
  40. {
  41.     char *pa;
  42.  
  43.     if (!cmd) {
  44.         cmd = *ptr;
  45.         if (!cmd)
  46.             return (NULL);
  47.     }
  48.     while (*cmd && strchr(toks, (int) *cmd))
  49.         ++cmd;
  50.  
  51.     if (!*cmd)
  52.         return (NULL);
  53.  
  54.     if (pa = strpbrk(cmd, toks))
  55.         *pa++ = 0;
  56.     *ptr = pa;
  57.     return (cmd);
  58. }
  59.  
  60. static void ParseConfigString(struct XPR_IO * IO, char *str)
  61. {
  62.     char *delim = ",";
  63.     char *tokptr;
  64.     char *dupstr, *zz;
  65.  
  66.     dupstr = AllocMem(strlen(str) + 1, MEMF_PUBLIC);
  67.     if (!dupstr)
  68.         return;
  69.  
  70.     strcpy(dupstr, str);
  71.  
  72.     zz = MYstrtok(dupstr, delim, &tokptr);
  73.  
  74.     if (zz)
  75.         do {
  76.             switch (toupper((int) *zz)) {
  77.             case 'T':
  78.                 switch (toupper((int) *(zz + 1))) {
  79.                 case '0':
  80.                     IO->xpr_data->ascii = 0;
  81.                     break;
  82.                 case '1':
  83.                     IO->xpr_data->ascii = 1;
  84.                     break;
  85.                 default:
  86.                     DisplayBeep(NULL);
  87.                     break;
  88.                 }
  89.                 break;
  90.             case 'C':
  91.                 switch (*(zz + 1)) {
  92.                 case '0':
  93.                     IO->xpr_data->crc_conf = 0;
  94.                     break;
  95.                 case '1':
  96.                     IO->xpr_data->crc_conf = 1;
  97.                     break;
  98.                 default:
  99.                     DisplayBeep(NULL);
  100.                     break;
  101.                 }
  102.                 break;
  103.             case 'K':
  104.                 switch (*(zz + 1)) {
  105.                 case '0':
  106.                     IO->xpr_data->big = 0;
  107.                     break;
  108.                 case '1':
  109.                     IO->xpr_data->big = 1;
  110.                     break;
  111.                 default:
  112.                     DisplayBeep(NULL);
  113.                     break;
  114.                 }
  115.                 break;
  116.             default:
  117.                 DisplayBeep(NULL);
  118.                 break;
  119.             }
  120.             zz = MYstrtok(0, delim, &tokptr);
  121.         } while (zz);
  122.  
  123.     FreeMem(dupstr, strlen(str) + 1);
  124. }
  125.  
  126. long XProtocolSetup(struct XPR_IO * IO)
  127. {
  128.     long (*xupdate) (), (*xgets) (), (*xoptions) () = NULL;
  129.     struct XPR_UPDATE xpru;
  130.     char buffy[128];
  131.  
  132.     if ((xupdate = IO->xpr_update) == NULL)
  133.         return (0);
  134.     if ((xgets = IO->xpr_gets) == NULL)
  135.         return (0);
  136.  
  137.     if (IO->xpr_extension >= 1)
  138.         xoptions = IO->xpr_options;
  139.  
  140.     /*
  141.      * Allocate a bit of memory for a data buffer
  142.      */
  143.     if (IO->xpr_data == NULL) {
  144.         IO->xpr_data = AllocMem(sizeof(struct XProtocolData), MEMF_PUBLIC | MEMF_CLEAR);
  145.         if (!IO->xpr_data) {
  146.             xpru.xpru_updatemask = XPRU_ERRORMSG;
  147.             xpru.xpru_errormsg = "XModem - Out of memory!";
  148.             calla(xupdate, &xpru);
  149.             return (0L);
  150.         }
  151.         IO->xpr_data->buffer = &IO->xpr_data->packet[3];
  152.     }
  153.     /* If setup string isn't handed to us, ask questions */
  154.  
  155.     if (IO->xpr_filename == NULL) {
  156.         if (xoptions) {
  157.             struct xpr_option *opti[4];
  158.  
  159.             struct xpr_option opti3 =
  160.             {"Text Mode", XPRO_BOOLEAN, NULL, 4};
  161.             struct xpr_option opti2 =
  162.             {"1K Blocks", XPRO_BOOLEAN, NULL, 4};
  163.             struct xpr_option opti1 =
  164.             {"CRC", XPRO_BOOLEAN, NULL, 4};
  165.             struct xpr_option opti0 =
  166.             {"XModem options:", XPRO_HEADER, NULL, 0};
  167.  
  168.             /* kludge because of manx aztec 5.0b stupid bug */
  169.             opti[0] = &opti0;
  170.             opti[1] = &opti1;
  171.             opti[2] = &opti2;
  172.             opti[3] = &opti3;
  173.  
  174.             opti1.xpro_value = AllocMem(4, MEMF_PUBLIC);
  175.             if (opti1.xpro_value) {
  176.                 if (IO->xpr_data->crc_conf)
  177.                     strcpy(opti1.xpro_value, "on");
  178.                 else
  179.                     strcpy(opti1.xpro_value, "off");
  180.             }
  181.             opti2.xpro_value = AllocMem(4, MEMF_PUBLIC);
  182.             if (opti2.xpro_value) {
  183.                 if (IO->xpr_data->big)
  184.                     strcpy(opti2.xpro_value, "on");
  185.                 else
  186.                     strcpy(opti2.xpro_value, "off");
  187.             }
  188.             opti3.xpro_value = AllocMem(4, MEMF_PUBLIC);
  189.             if (opti3.xpro_value) {
  190.                 if (IO->xpr_data->ascii)
  191.                     strcpy(opti3.xpro_value, "on");
  192.                 else
  193.                     strcpy(opti3.xpro_value, "off");
  194.             }
  195.  
  196.             callad(xoptions, &opti, IO->xpr_finfo?3:4);
  197.  
  198.             if (
  199.                    (!strcmp(opti1.xpro_value, "yes")) ||
  200.                    (!strcmp(opti1.xpro_value, "on"))
  201.                 )
  202.                 IO->xpr_data->crc_conf = 1;
  203.             else
  204.                 IO->xpr_data->crc_conf = 0;
  205.  
  206.             if (
  207.                    (!strcmp(opti2.xpro_value, "yes")) ||
  208.                    (!strcmp(opti2.xpro_value, "on"))
  209.                 )
  210.                 IO->xpr_data->big = 1;
  211.             else
  212.                 IO->xpr_data->big = 0;
  213.  
  214.             if (
  215.                    (!strcmp(opti3.xpro_value, "yes")) ||
  216.                    (!strcmp(opti3.xpro_value, "on"))
  217.                 )
  218.                 IO->xpr_data->ascii = 1;
  219.             else
  220.                 IO->xpr_data->ascii = 0;
  221.  
  222.             if (opti3.xpro_value)
  223.                 FreeMem(opti3.xpro_value, 4);
  224.             if (opti2.xpro_value)
  225.                 FreeMem(opti2.xpro_value, 4);
  226.             if (opti1.xpro_value)
  227.                 FreeMem(opti1.xpro_value, 4);
  228.         } else {
  229.             sprintf(buffy, "T%d,C%d,K%d", IO->xpr_data->ascii, IO->xpr_data->crc_conf, IO->xpr_data->big);
  230.             callaa(xgets, "Enter XModem config string (A<0|1>,C<0|1>,K<0|1>)", buffy);
  231.             ParseConfigString(IO, buffy);
  232.         }
  233.     } else
  234.         ParseConfigString(IO, IO->xpr_filename);
  235.  
  236.     return (1);
  237. }
  238.  
  239. void PutCH(struct XPR_IO * IO, int ch)
  240. {
  241.     long (*xfwrite) ();
  242.  
  243.     if ((xfwrite = IO->xpr_fwrite) == NULL)
  244.         return;
  245.  
  246.     if (IO->xpr_data->savech == '\032')
  247.         return;
  248.  
  249.     if (IO->xpr_data->savech == '\r') {
  250.         if (ch != '\n') {
  251.             unsigned char blou = IO->xpr_data->savech;
  252.  
  253.             calladda(xfwrite, &blou, 1, 1, (void *) IO->xpr_data->fp);
  254.         }
  255.         IO->xpr_data->savech = 0;
  256.     }
  257.     if (IO->xpr_data->ascii) {
  258.         if (ch == '\r' || ch == '\032')
  259.             IO->xpr_data->savech = ch;
  260.         else {
  261.             unsigned char blou = ch;
  262.  
  263.             calladda(xfwrite, &blou, 1, 1, (void *) IO->xpr_data->fp);
  264.         }
  265.     } else {
  266.         unsigned char blou = ch;
  267.  
  268.         calladda(xfwrite, &blou, 1, 1, (void *) IO->xpr_data->fp);
  269.     }
  270. }
  271.  
  272. int GetCH(struct XPR_IO * IO)
  273. {
  274.     unsigned char chc;
  275.     int ch;
  276.     long (*xfread) ();
  277.  
  278.     if ((xfread = IO->xpr_fread) == NULL)
  279.         return (0L);
  280.  
  281.     if (IO->xpr_data->savech) {
  282.         ch = IO->xpr_data->savech;
  283.         IO->xpr_data->savech = 0;
  284.     } else {
  285.         if (!calladda(xfread, &chc, 1, 1, (void *) IO->xpr_data->fp))
  286.             ch = EOF;
  287.         else
  288.             ch = (int) chc;
  289.  
  290.         if (IO->xpr_data->ascii) {
  291.             if (ch == '\n') {
  292.                 IO->xpr_data->savech = ch;
  293.                 ch = '\r';
  294.             } else if (ch == EOF) {
  295.                 IO->xpr_data->savech = EOF;
  296.                 ch = '\032';
  297.             }
  298.         }
  299.     }
  300.     return (ch);
  301. }
  302.  
  303. void SerialTransparent(struct XPR_IO * IO)
  304. {
  305.     if (IO->xpr_setserial) {
  306.         IO->xpr_data->serialbits = calld(IO->xpr_setserial, -1);
  307.         calld(IO->xpr_setserial, ((IO->xpr_data->serialbits) & ~(1 + 2 + 4 + 64 + 256 + 1024 + 2048 + 4096)) | 128);
  308.     }
  309. }
  310.  
  311. void SerialRestore(struct XPR_IO * IO)
  312. {
  313.     if (IO->xpr_setserial)
  314.         calld(IO->xpr_setserial, IO->xpr_data->serialbits);
  315. }
  316.  
  317. long XProtocolSend(struct XPR_IO * IO)
  318. {
  319.     long brkflag = 0, size=0, oldascii;
  320.     long (*xupdate) (), (*xswrite) (), (*xfopen) (), (*xfclose) (),
  321.      (*xfread) (), (*xsread) (), (*xfinfo) (), (*xchkabort) (void);
  322.     struct XPR_UPDATE xpru;
  323.  
  324.     if ((xupdate = IO->xpr_update) == NULL)
  325.         return (0L);
  326.     if ((xswrite = IO->xpr_swrite) == NULL)
  327.         return (0L);
  328.     if ((xfopen = IO->xpr_fopen) == NULL)
  329.         return (0L);
  330.     if ((xfclose = IO->xpr_fclose) == NULL)
  331.         return (0L);
  332.     if ((xfread = IO->xpr_fread) == NULL)
  333.         return (0L);
  334.     if ((xsread = IO->xpr_sread) == NULL)
  335.         return (0L);
  336.     if ((xchkabort = IO->xpr_chkabort) == NULL)
  337.         return (0L);
  338.  
  339.     oldascii=IO->xpr_data->ascii;
  340.  
  341.     if(xfinfo = IO->xpr_finfo) {
  342.         size = callad(xfinfo, IO->xpr_filename, 1);    /* get file size */
  343.         switch(callad(xfinfo, IO->xpr_filename, 2)) {    /* get file type */
  344.             case 1: IO->xpr_data->ascii=0; break; /* Binary */
  345.             case 2: IO->xpr_data->ascii=1; break; /* Text */
  346.             default: break; /* uh? */
  347.         }
  348.     }
  349.  
  350.     IO->xpr_data->fp = callaa(xfopen, IO->xpr_filename, "r");
  351.     if (!IO->xpr_data->fp) {
  352.         xpru.xpru_updatemask = XPRU_ERRORMSG | XPRU_FILENAME;
  353.         xpru.xpru_errormsg = "Failed to open input file";
  354.         xpru.xpru_filename = IO->xpr_filename;
  355.         calla(xupdate, &xpru);
  356.         IO->xpr_data->ascii=oldascii;
  357.         return (0L);
  358.     }
  359.     /* Initialize display */
  360.     bm_infoinit(IO, 1, size);
  361.  
  362.     SerialTransparent(IO);
  363.  
  364.     if (!dl_snd(IO, GetCH))
  365.         brkflag = 2;
  366.  
  367.     SerialRestore(IO);
  368.  
  369.     if (IO->xpr_data->abort == 1)
  370.         brkflag = 1;
  371.  
  372.     calla(xfclose, (void *) IO->xpr_data->fp);
  373.  
  374.     xpru.xpru_updatemask = XPRU_MSG;
  375.     switch (brkflag) {
  376.     case 0:
  377.         xpru.xpru_msg = "Done";
  378.         break;
  379.     case 1:
  380.         xpru.xpru_msg = "Aborted";
  381.         break;
  382.     case 2:
  383.         xpru.xpru_msg = "Failed";
  384.         break;
  385.     }
  386.     calla(xupdate, &xpru);
  387.  
  388.     IO->xpr_data->ascii=oldascii;
  389.  
  390.     if (brkflag)
  391.         return (0);
  392.     else
  393.         return (1);
  394. }
  395.  
  396. long XProtocolReceive(struct XPR_IO * IO)
  397. {
  398.     long brkflag = 0, oldascii;
  399.     long (*xupdate) (), (*xswrite) (), (*xfopen) (), (*xfclose) (),
  400.      (*xfwrite) (), (*xsread) (), (*xfinfo) ();
  401.     struct XPR_UPDATE xpru;
  402.  
  403.     if ((xupdate = IO->xpr_update) == NULL)
  404.         return (0L);
  405.     if ((xswrite = IO->xpr_swrite) == NULL)
  406.         return (0L);
  407.     if ((xfopen = IO->xpr_fopen) == NULL)
  408.         return (0L);
  409.     if ((xfclose = IO->xpr_fclose) == NULL)
  410.         return (0L);
  411.     if ((xfwrite = IO->xpr_fwrite) == NULL)
  412.         return (0L);
  413.     if ((xsread = IO->xpr_sread) == NULL)
  414.         return (0L);
  415.  
  416.     oldascii=IO->xpr_data->ascii;
  417.  
  418.     if(xfinfo = IO->xpr_finfo) switch(callad(xfinfo, IO->xpr_filename, 2)) {    /* get file type */
  419.         case 1: IO->xpr_data->ascii=0; break; /* Binary */
  420.         case 2: IO->xpr_data->ascii=1; break; /* Text */
  421.         default: break; /* uh? */
  422.     }
  423.  
  424.     IO->xpr_data->fp = callaa(xfopen, IO->xpr_filename, "w");
  425.     if (IO->xpr_data->fp == NULL) {
  426.         xpru.xpru_updatemask = XPRU_ERRORMSG | XPRU_FILENAME;
  427.         xpru.xpru_errormsg = "Failed to open output file";
  428.         xpru.xpru_filename = IO->xpr_filename;
  429.         calla(xupdate, &xpru);
  430.         IO->xpr_data->ascii=oldascii;
  431.         return (0L);
  432.     }
  433.     IO->xpr_data->savech = 0;
  434.  
  435.     /* Initialize display */
  436.     bm_infoinit(IO, 0, 0);
  437.  
  438.     SerialTransparent(IO);
  439.  
  440.     if (!dl_rcv(IO, PutCH))
  441.         brkflag = 2;
  442.  
  443.     SerialRestore(IO);
  444.  
  445.     if (IO->xpr_data->abort == 1)
  446.         brkflag = 1;
  447.  
  448.     /*
  449.      * Close the file
  450.      */
  451.     calla(xfclose, (void *) IO->xpr_data->fp);
  452.  
  453.     xpru.xpru_updatemask = XPRU_MSG;
  454.     switch (brkflag) {
  455.     case 0:
  456.         xpru.xpru_msg = "Done";
  457.         break;
  458.     case 1:
  459.         xpru.xpru_msg = "Aborted";
  460.         break;
  461.     case 2:
  462.         xpru.xpru_msg = "Failed";
  463.         break;
  464.     }
  465.  
  466.     calla(xupdate, &xpru);
  467.  
  468.     IO->xpr_data->ascii=oldascii;
  469.  
  470.     if (brkflag) {
  471.         long (*xsflush)(void);
  472.  
  473.         if (xsflush = IO->xpr_sflush) xsflush();
  474.         return (0);
  475.     } else return (1);
  476. }
  477.  
  478. /**
  479. *
  480. *   The following is stuff replacing mdio.c
  481. *
  482. **/
  483.  
  484. /*
  485.  * md_get - get a character from the modem with timeout
  486.  */
  487. int md_get(struct XPR_IO * IO, int tmo)
  488. {
  489.     int ch;
  490.     unsigned char chc;
  491.     long howmany;
  492.     long (*xchkabort) (void);
  493.  
  494.     xchkabort = IO->xpr_chkabort;
  495.  
  496.     if (xchkabort())
  497.         if (!IO->xpr_data->abort)
  498.             IO->xpr_data->abort = 1;
  499.  
  500.     if (IO->xpr_data->abort) {
  501.         calladd(IO->xpr_sread, &chc, 1, 1);
  502.         return (DT_ERR);
  503.     }
  504.     howmany = calladd(IO->xpr_sread, &chc, 1, tmo * 1000000L);
  505.     ch = chc;
  506.  
  507.     if (!howmany)
  508.         return (DT_TIME);
  509.     return (ch);
  510. }
  511.  
  512. /*
  513.  * md_put - output a character to the modem
  514.  */
  515. void md_put(struct XPR_IO * IO, int ch)
  516. {
  517.     unsigned char chc = ch;
  518.  
  519.     callad(IO->xpr_swrite, &chc, 1);
  520. }
  521.  
  522. /*
  523.  * md_write - write a packet to the modem
  524.  */
  525. void md_write(struct XPR_IO * IO, char *buf, int len)
  526. {
  527.     callad(IO->xpr_swrite, buf, len);
  528. }
  529.